///@file Tensor2.h
///@brief Declaration of the class representing a second order tensor
///@author Arnaud Duval
///@version 0.0
///@date 2009/10/29


#ifndef TENSOR2_H
#define TENSOR2_H

#include <assert.h>
#include <iostream>
#include "Matrix.h"

///@class Tensor2
///@brief Class defining a second order tensor
/// A Tensor2 derive from a Matrix
class Tensor2 : public Matrix
{
	///@brief Number of rows
	using Matrix::nbRows;
	///@brief Number of columns
	using Matrix::nbColumns;
	
	public :  
		///@brief Default constructor
		Tensor2() : Matrix() {}
		///@brief Constructorr giving the dimension
		Tensor2(unsigned int i) : Matrix(i,i) {}
		///@brief Copy constructor
		Tensor2(const Tensor2 &t) : Matrix(t) {}
		///@brief Copy constructor for temporary objects
		Tensor2(Tensor2 *t) : Matrix(t) {}
		///@brief Destructor
		~Tensor2() {}
		///@brief Return dimension
		unsigned int Dim();
		///@brief Return deviator part of tensor
		Tensor2 Dev();
        ///@brief Return a Kronecker tensor
        Tensor2 Delta(unsigned int);
        ///@brief Return Von Mises equivalent for stresses
        double VMEquivStress();

        ///@brief Overload of + operator
        Tensor2 operator+ (const Tensor2&);
        ///@brief Overload of - operator
        Tensor2 operator- (const Tensor2&);
        ///@brief Overload of / operator : division by a scalar
        Tensor2 operator/ (const double&);
        ///@brief Overload of * operator : multiplication by a scalar
        Tensor2 operator* (const double&);
        ///@brief Overload of = operator
        
        

        ///@brief Overload of * operator : product scalar * tensor
        friend Tensor2 operator* (const double&, const Tensor2&);

		///@brief Overload of | operator : contracted product A_ij = B_ik C_kj
		friend Tensor2 operator | (const Tensor2&, const Tensor2&);
		///@brief Overload of || operator : double contracted product A = B_ij C_ji
		friend double operator || (const Tensor2&, const Tensor2&);
};


#endif
